---
title: Queries, Mutations and Subscriptions
description: Guide for adding queries, mutations and subscriptions to your schema
---

There are a few different ways to add queries to your schema. The simplest way is to define a
`Query` type with your query fields using the `builder.queryType()` method.

```typescript
builder.queryType({
  fields: (t) => ({
    // Add query for a simple scalar type
    hello: t.string({
      resolve: () => 'hello, world!',
    }),
    // Add a query for an object type
    giraffe: t.field({
      type: Giraffe,
      resolve: () => ({
        name: 'James',
      }),
    }),
    // Add a query for a list of objects
    giraffes: t.field({
      type: [Giraffe],
      resolve: () => [
        {
          name: 'James',
        },
      ],
    }),
  }),
});

const Giraffe = builder.objectRef<{ name: string }>('Giraffe');

Giraffe.implement({
  fields: (t) => ({
    name: t.exposeString('name'),
  }),
});
```

You can only use `builder.queryType()` once in your schema, because it is responsible for defining
the `Query` type itself. If you want to split up your queries and add query fields individually, you
can use the `builder.queryField()` method to add individual query fields to the `Query` type.

```typescript
// You will still need to define the `Query` type somewhere in your schema to add individual query fields
builder.queryType({});

builder.queryField('hello', (t) =>
  t.string({
    resolve: () => 'hello, world!',
  }),
);

builder.queryField('giraffe', (t) =>
  t.field({
    type: Giraffe,
    resolve: () => ({
      name: 'James',
    }),
  }),
);
```

If you want to add multiple query fields at once, you can use the `builder.queryFields()` method.

```typescript
builder.queryFields((t) => ({
  hello: t.string({
    resolve: () => 'hello, world!',
  }),
  giraffe: t.field({
    type: Giraffe,
    resolve: () => ({
      name: 'James',
    }),
  }),
}));
```

# Mutations

Mutations work just like queries, and you can use the `builder.mutationType()`,
`builder.mutationField()`, and `builder.mutationFields()` methods to add mutations to your schema.

```typescript
builder.mutationType({
  fields: (t) => ({
    // Add mutation that returns a simple boolean
    post: t.boolean({
      args: {
        message: t.arg.string(),
      },
      resolve: async (root, args) => {
        // Do something with the message
        const success = await messageClient.postMessage(args.message);

        return success;
      },
    }),
  }),
});

builder.mutationField('createGiraffe', (t) =>
  t.field({
    type: Giraffe,
    args: {
      name: t.arg.string(),
    },
    resolve: async (root, args) => {
      const giraffe = {
        name: args.name,
      };

      await db.giraffes.create(giraffe);

      return giraffe;
    },
  }),
);
```
# Subscriptions

Subscriptions too work just like queries and mutations where you can use the `builder.subscriptionType()`,
`builder.subscriptionField()`, and `builder.subscriptionFields()` methods to add subscriptions to your
schema.

```typescript
builder.mutationType({
  fields: (t) => ({
    incrementCount: t.int({
      resolve: (_parent, _args, ctx) => {
        ctx.count.value += 1;
        ctx.pubSub.publish('COUNT_INCREMENT', ctx.count.value);
        return ctx.count.value;
      },
    }),
  }),
});

builder.subscriptionType({
  fields: (t) => ({
    incrementedCount: t.int({
      subscribe: (_parent, _args, ctx) => ctx.pubSub.subscribe('COUNT_INCREMENT'),
      resolve: (count) => count,
    }),
  }),
});
```

import { Callout } from 'fumadocs-ui/components/callout';

<Callout type="warn">
  Ensure that the `subscribe` function is always defined before the `resolve` function,
  otherwise you may run into issues with the resolver arguments not being typed correctly.
</Callout>
